/**
参考网址：https://blog.csdn.net/qq_43766999/article/details/120708054

OpenLayers实战（八）行政区域遮罩和反遮罩

https://blog.csdn.net/yyxy_gis/article/details/120193305
openlayers实现四周遮罩，特定区域透明效果
*/
<template>
  <div>
    <div ref="map" id="map"></div>
    <div class="btns">
      <button @click="drawConver()">遮罩</button>
      <button @click="drawUnConver()">反遮罩</button>
    </div>
  </div>
</template>

<script>
  import "ol/ol.css";
  import { Map, View, Feature } from "ol";
  import TileLayer from "ol/layer/Tile";
  import XYZ from "ol/source/XYZ";
  import VectorSource from "ol/source/Vector";
  import VectorLayer from "ol/layer/Vector";
  import { Style, Circle as CircleStyle, Fill, Stroke, } from "ol/style";
  import { Point,LineString } from "ol/geom";
  import {  Polygon } from "ol/geom";

  export default {
    name: "AppConver",
    data() {
      return {
        map: null,
        vectorLayer: null,//模拟数据源
        converLayer: null,
        reverseLayer: null,
      };
    },
    mounted() {

      // 创建地图
      this.initMap();

      // 创建要素图层
      this.vectorLayer = new VectorLayer({
        source: new VectorSource({
          features: [
            new Feature({
              geometry: new Point([120.0, 30.0]),
              name: 'A'
            }),
            new Feature({
              geometry: new Point([120.1, 30.1]),
              name: 'B'
            }),
            new Feature({
              geometry: new Point([120.2, 30.2]),
              name: 'C'
            })
          ]
        }),
        style: new Style({
          image: new CircleStyle({
            radius: 30,
            fill: new Fill({
              // color: 'blue'
              color: '#8B8989'
            })
          })
        })
      });
      this.map.addLayer(this.vectorLayer);

      this.addConverLayer();
      this.addReverseLayer();
    },
    methods: {
      /**
      * 初始化一个 openlayers 地图
      */
      initMap() {
        this.map = new Map({
          target: "map",
          view: new View({
            center: [120.0, 30.0],
            zoom: 10,
            projection: "EPSG:4326",
          }),
        });
        var gaodeLayer = new TileLayer({
          source: new XYZ({
            url: "http://webrd0{1-4}.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=8&x={x}&y={y}&z={z}"
          })
        });
        this.map.addLayer(gaodeLayer);
        this.map.removeLayer(gaodeLayer);
      },

      // 准备反转遮罩层
      addConverLayer() {
        let source = new VectorSource();
        // 遮罩的样式
        let style = new Style({
          fill: new Fill({
            color: "rgba(8,31,63,0.6)",
          }),
          stroke: new Stroke({
            color: "rgb(8,91,163)",
            width: 1
          })
        });
        let converLayer = new VectorLayer({ source, style });
        this.converLayer = converLayer;
        this.map.addLayer(converLayer);

        console.log('---- addConverLayer---- ')
      },
      /**
     * 开始操作
     * @param data 某个行政区域的轮廓数据
     */
      drawConver() {
        let features = this.vectorLayer.getSource().getFeatures();
        // 直接遍历添加feature即可
        features.forEach(item => {
          if (item.get("name") === 'A') {
            console.log('drawConver:  ',item.get("name"))
            this.converLayer.getSource().addFeature(item);
          }
        });
      },

        // 准备反转遮罩层
    addReverseLayer(){
        let source =new VectorSource();
        // 遮罩的样式
        let style = new  Style({
            fill: new  Fill({
                color: "rgba(8,31,63,0.6)",
            }),
            stroke: new  Stroke({
                color: "rgb(8,91,163)",
                width: 1
            })
        });
        let reverseLayer = new  VectorLayer({ source,  style });
        this.reverseLayer = reverseLayer;
        this.map.addLayer(reverseLayer);
    },
    /**
	 * 开始操作
	 * @param data 某个行政区域的轮廓数据
	 */
    drawUnConver( ) {
        // 将data转换为feature
        const dataForMart =  this.vectorLayer.getSource().getFeatures();
        // 得到反转擦除后遮盖层数据
        const converGeom = erase(dataForMart);
        const convertFt = new  Feature({ geometry: converGeom });
        this.converLayer.getSource().addFeature(convertFt);

        function erase(geom) {
            const polygonRing =  Polygon.fromExtent([-180, -90, 180, 90]);
            // 擦除操作
            for (let i = 0, len = geom.length; i < len; i++) {
                let g = geom[i].getGeometry();
                const coords = g.getCoordinates();
                coords.forEach(coord => {
                    const linearRing = new  LineString(coord[0]);
                    polygonRing.appendLinearRing(linearRing);
                });
            }
            return polygonRing;
        }
    },
    }

  };

</script>

<style scoped>
  #map {
    width: 100%;
    height: 100%;
    position: absolute;
    top: 0;
    left: 0;
  }

  /*移除OSM的链接*/
  :deep(.ol-attribution) {
    display: none;
  }

  .btns {
    position: fixed;
    top: 100px;
    left: 200px;
  }
</style>